using System;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Collections;
using System.Xml;
using System.Text;
using System.Collections.Specialized;

namespace Core.Graphics
{
    [Serializable()]
    [DefaultPropertyAttribute("CollisionLayer")]
    [XmlRoot("CollisionLayer")]
    public class CollisionLayer : IXmlSerializable
    {
        [XmlElement("TileCollection")]
        public CollisionTileCollection Tiles { get { return _CollisionTiles; } set { _CollisionTiles = value; } }
        [XmlAttribute("Width")]
        public int Width { get { return _Width; } set { _Width = value; } }
        [XmlAttribute("Height")]
        public int Height { get { return _Height; } set { _Height = value; } }

        protected int _Width;
        protected int _Height;
        protected CollisionTileCollection _CollisionTiles;

        public CollisionLayer(CollisionTileCollection Tiles, int Width, int Height)
        {
            _CollisionTiles = Tiles;
            _Width = Width;
            _Height = Height;
        }

        public CollisionLayer(int Width, int Height)
        {
            _CollisionTiles = CollisionTileCollection.GetCollisionTilesForEmptyCollisionLayer(Width, Height);
            _Width = Width;
            _Height = Height;
        }

        public CollisionLayer() { /*XML Serialization*/ }

        public virtual CollisionTile GetCollisionAtLocation(int x, int y)
        {
            if (x >= 0 && y >= 0)
                return _CollisionTiles[y * _Height + x];
            else
                return CollisionTile.EmptyCollision;
        }

        public virtual void SetCollisionAtLocation(CollisionTile tile, int x, int y)
        {
            if (x >= 0 && y >= 0)
                _CollisionTiles[y * _Height + x] = tile;
        }

        #region IXmlSerializable Members

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            //Read in basic properties
            _Width = Convert.ToInt32(reader.GetAttribute("Width"));
            _Height = Convert.ToInt32(reader.GetAttribute("Height"));
            //Create CollisionTileCollection
            _CollisionTiles = new CollisionTileCollection();
            //Read Tile String
            string strAllTiles = reader.GetAttribute("Tiles");

            //---load tiles----
            //If no collision tiles are specified, then load in a full batch of empty collision tiles
            if (strAllTiles == "")
            {
                for (int i = 0; i < _Width * _Height; i++)
                {
                    _CollisionTiles.Add(CollisionTile.EmptyCollision);
                }
            }
            else
            {
                //If we have collision tiles, split them at the comma and get value
                char[] ch = new char[1];
                ch[0] = ',';

                string[] Tiles = strAllTiles.Split(ch);

                foreach (string str in Tiles)
                {
                    //if empty string then add blank tile
                    if (str == "")
                    {
                        _CollisionTiles.Add(CollisionTile.EmptyCollision);
                    }
                    else
                    {
                        //Convert the string to an in32, then get collision tile from the bit vector
                        _CollisionTiles.Add(
                            CollisionTile.GetCollisionTileFromBitVector(Convert.ToInt32(str)));
                    }
                }
            }
        }

        public void WriteXml(XmlWriter writer)
        {
            //Write Properties to xml
            writer.WriteAttributeString("Width", _Width.ToString());
            writer.WriteAttributeString("Height", _Height.ToString());

            //Write CollisionTile Info
            int notblank = 0;

            StringBuilder sb = new StringBuilder();

            foreach (CollisionTile ct in _CollisionTiles)
            {
                int Data = CollisionTile.GetCollisionTileAsBitVector(ct);

                if (Data == 0)
                {
                    //If this collision tile is empty add a ',' to move to next
                    sb.Append(',');
                }
                else
                {
                    //Convert the collision Tile to a bitVector32 (int32) and append to the data string
                    sb.Append(Data.ToString() + ",");
                    //If this tile is not blank add one.
                    notblank++;
                }
            }

            if (notblank == 0)
            {
                //If there were no tiles in whole layer save empty string
                sb = new StringBuilder(string.Empty);
            }

            writer.WriteAttributeString("Tiles", sb.ToString());
        }

        #endregion
    }
}
